EffTox - Nuts and Bolts

This notebook demonstrates the nuts and bolts of EffTox, the technical details rather than the general user interface. For example, I use it to check calculations in implementations in other languages. For a general EffTox usage tutorial, use EffTox.ipynb.


In [1]:
import numpy as np

In [2]:
from clintrials.dosefinding.efftox import _pi_E, _pi_T, _pi_ab, _L_n, scale_doses

In the Matchpoint trial, the daily doses of Ponatinib under investigation were:

  • 7.5mg
  • 15mg
  • 30mg
  • 45mg

In [3]:
real_doses = [7.5, 15, 30, 45]

In [4]:
scaled_doses = scale_doses(real_doses)

In [5]:
scaled_doses


Out[5]:
array([-0.96780025, -0.27465307,  0.41849411,  0.82395922])

Create some notional values for the two coefficients in the toxicity logit:


In [6]:
alpha0 = np.array([0.0, 1.0, 0.2])
alpha1 = np.array([1.0, -0.5, -1.0])

In [7]:
_pi_T(scaled_doses[1], alpha0, alpha1)


Out[7]:
array([ 0.43176513,  0.75718845,  0.61648448])

In [8]:
_pi_T(scaled_doses[3], alpha0, alpha1)


Out[8]:
array([ 0.69507612,  0.6429108 ,  0.34888153])

Create some notional values for the three coefficients in the efficacy logit:


In [9]:
beta0 = np.array([-0.5, -1.0, 0.2])
beta1 = np.array([-1.0, -2.0, 1.0])
beta2 = np.array([0.1, 0.2, -0.1])

In [10]:
_pi_E(scaled_doses[0], beta0, beta1, beta2)


Out[10]:
array([ 0.63679121,  0.75453142,  0.29703357])

In [11]:
_pi_E(scaled_doses[2], beta0, beta1, beta2)


Out[11]:
array([ 0.28884907,  0.14161255,  0.64588057])

Create some notional values for psi


In [12]:
psi = np.array([-5.0, 0.7, 5.0])

Join it all up


In [13]:
_pi_ab(scaled_doses[0], 0, 1, alpha0, alpha1, beta0, beta1, beta2, psi)


Out[13]:
array([ 0.50699895,  0.1300797 ,  0.03319174])

In [14]:
_pi_ab(scaled_doses[2], 1, 1, alpha0, alpha1, beta0, beta1, beta2, psi)


Out[14]:
array([ 0.22272268,  0.0886512 ,  0.23205335])

Now create some notional cases: 1N 2E 3T, using the nomenclature of Implementing the EffTox dose-finding design in the Matrchpoint trial, by Brock et al.


In [15]:
X = [(scaled_doses[0], 0, 0), (scaled_doses[1], 0, 1), (scaled_doses[2], 1, 0)]

Calculate the compound likelihood under the parameter combinations


In [16]:
_L_n(X, alpha0, alpha1, beta0, beta1, beta2, psi)


Out[16]:
array([ 0.0461508 ,  0.0016879 ,  0.00166065])

What do these "nuts and bolts" contribute to?


In [17]:
from clintrials.dosefinding.efftox import efftox_get_posterior_probs, efftox_get_posterior_params

In [18]:
cases = [(1, 0, 0), (2, 0, 1), (3, 1, 0)]

In [19]:
from scipy.stats import norm

In [20]:
mu_t_mean, mu_t_sd = -5.4317, 2.7643
beta_t_mean, beta_t_sd = 3.1761, 2.7703
mu_e_mean, mu_e_sd = -0.8442, 1.9786
beta_e_1_mean, beta_e_1_sd = 1.9857, 1.9820
beta_e_2_mean, beta_e_2_sd = 0, 0.2
psi_mean, psi_sd = 0, 1
priors = [
    norm(loc=mu_t_mean, scale=mu_t_sd),
    norm(loc=beta_t_mean, scale=beta_t_sd),
    norm(loc=mu_e_mean, scale=mu_e_sd),
    norm(loc=beta_e_1_mean, scale=beta_e_1_sd),
    norm(loc=beta_e_2_mean, scale=beta_e_2_sd),
    norm(loc=psi_mean, scale=psi_sd),
    ]

In [21]:
np.random.seed(123)
probs, thing = efftox_get_posterior_probs(cases, priors, scaled_doses, tox_cutoff=0.4, eff_cutoff=0.45, n=10**6)

In [22]:
prob_tox, prob_eff, prob_acc_tox, prob_acc_eff = zip(*probs)

In [23]:
prob_tox


Out[23]:
(0.018196222456040894,
 0.077553494319095986,
 0.46887905231555532,
 0.7362166520914275)

In [24]:
prob_acc_tox


Out[24]:
(0.99320475928614682,
 0.96901298353152288,
 0.47169110764562977,
 0.15821473148281351)

In [25]:
prob_eff


Out[25]:
(0.22013447186187166,
 0.30243690338867141,
 0.4600635818911748,
 0.54455913160027725)

In [26]:
prob_acc_eff


Out[26]:
(0.17175012210796936,
 0.23131955018761038,
 0.47183893926980514,
 0.61438570166558037)

Higher precision

Warning: this takes a while and peaks memory usage (on my machine) at roughly 1Gb


In [46]:
np.random.seed(123)
probs, thing = efftox_get_posterior_probs(cases, priors, scaled_doses, tox_cutoff=0.4, eff_cutoff=0.45, n=10**7)

In [48]:
prob_tox, prob_eff, prob_acc_tox, prob_acc_eff = zip(*probs)

In [49]:
prob_tox


Out[49]:
(0.017721596042804065,
 0.077300802973282567,
 0.47664283361147941,
 0.74481378531497666)

In [50]:
prob_acc_tox


Out[50]:
(0.99364311416251194,
 0.96463287117519392,
 0.43994562896133421,
 0.156595042211854)

In [51]:
prob_eff


Out[51]:
(0.21301090872543804,
 0.2985971523841035,
 0.45994786342568222,
 0.54434065144599786)

In [52]:
prob_acc_eff


Out[52]:
(0.15485703706407367,
 0.2318339137152034,
 0.48924984978095742,
 0.60206723461811928)

In [54]:
efftox_get_posterior_params(cases, priors, scaled_doses, n=10**7)


Out[54]:
([(-2.2703011519429555,
   5.1516424515286898,
   -0.75467247679595473,
   1.2708491348927389,
   -0.0091021824701728229,
   -0.10086623116956173)],
 <clintrials.stats.ProbabilityDensitySample instance at 0x10da183b0>)

In [ ]: